package top.szhome.framework.core.tools.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import lombok.extern.slf4j.Slf4j;
import top.szhome.framework.core.tools.exception.JsonException;

import java.util.List;

/**
 * @author 唐加利
 * @date 2023/8/11
 **/
@Slf4j
public class JsonUtil {

    private static ObjectMapper MAPPER;

    /**
     * 初始化JSONG工具类mapper
     */
    public JsonUtil(){
        this(null);
    }

    /**
     * 初始化JSON工具类mapper
     * @param mapper    mapper对象
     */
    public JsonUtil(ObjectMapper mapper){
        if(mapper == null){
            try {
                mapper = SpringUtil.getBean(ObjectMapper.class);
            } catch (Exception e) {
                log.error("尝试从Spring容器加载ObjectMapper实例失败", e);
            }
        }

        if(mapper == null){
            mapper = new ObjectMapper();
//            mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        }

        MAPPER = mapper;
    }

    /**
     * 对象转JSON
     * @param object    待处理对象
     * @return  输出对象的JSON格式数据
     */
    public static String toJson(Object object){
        return toJson(object, false);
    }

    /**
     * 对象转JSON
     * @param object    待处理对象
     * @param pretty    是否格式化输出
     * @return  输出对象的JSON格式数据，视参数决定是否格式化输出
     */
    public static String toJson(Object object, boolean pretty){
        try {
            if(pretty){
                return MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(object);
            } else {
                return MAPPER.writeValueAsString(object);
            }
        } catch (JsonProcessingException e) {
            throw new JsonException(e);
        }
    }



    /**
     * JSON转对象
     * @param json      JSON字符串
     * @param clazz     期望转换类型
     * @param <T>       期望转换类型
     * @return 返回类型为T的对象
     */
    public static <T> T parseObject(String json, JavaType clazz) {
        try {
            return MAPPER.readValue(json, clazz);
        } catch (JsonProcessingException e) {
            throw new JsonException(e);
        }
    }

    /**
     * JSON转对象
     * @param json      JSON字符串
     * @param clazz     期望转换类型
     * @param <T>       期望转换类型
     * @return 返回类型为T的对象
     */
    public static <T> T parseObject(String json, Class<T> clazz) {
        try {
            return MAPPER.readValue(json, clazz);
        } catch (JsonProcessingException e) {
            throw new JsonException(e);
        }
    }

    /**
     * 根据Java范型转对象
     * @param json              JSON字符串
     * @param parametrized      被参数化的对象类型
     * @param parameterClasses  参数类型
     * @return
     */
    public static <T> T parseObject(String json, Class<T> parametrized, Class<?>... parameterClasses) {
        try {
            JavaType type = TypeFactory.defaultInstance().constructParametricType(parametrized, parameterClasses);
            return MAPPER.readValue(json, type);
        } catch (JsonProcessingException e) {
            throw new JsonException(e);
        }
    }

    /**
     * JSON转集合
     * @param json      JSON字符串
     * @param clazz     集合范型
     * @param <T>       范型类型
     * @return 返回范型为T的集合
     */
    public static <T> List<T> parseArray(String json, Class<T> clazz) {
        try {
            return (List)MAPPER.readValue(json, MAPPER.getTypeFactory().constructParametricType(List.class, new Class[]{ clazz }));
        } catch (JsonProcessingException e) {
            throw new JsonException(e);
        }
    }

}
